home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 1.toast / Sample Code / Contributed / SpriteWorld / SpriteWorld Files / Sources / SpriteLayer.c < prev    next >
Encoding:
Text File  |  2000-10-06  |  19.9 KB  |  744 lines  |  [TEXT/CWIE]

  1. ///--------------------------------------------------------------------------------------
  2. //    SpriteLayer.c
  3. //
  4. //    Portions are copyright: © 1991-94 Tony Myles, All rights reserved worldwide.
  5. //
  6. //    Description:    implementation of the sprite layers
  7. ///--------------------------------------------------------------------------------------
  8.  
  9. #ifndef __MEMORY__
  10. #include <Memory.h>
  11. #endif
  12.  
  13. #ifndef __SWCOMMON__
  14. #include <SWCommonHeaders.h>
  15. #endif
  16.  
  17. #ifndef __SPRITEWORLDUTILS__
  18. #include <SpriteWorldUtils.h>
  19. #endif
  20.  
  21. #ifndef __SPRITEWORLD__
  22. #include <SpriteWorld.h>
  23. #endif
  24.  
  25. #ifndef __SPRITELAYER__
  26. #include <SpriteLayer.h>
  27. #endif
  28.  
  29. #ifndef __SPRITE__
  30. #include <Sprite.h>
  31. #endif
  32.  
  33.  
  34.  
  35. ///--------------------------------------------------------------------------------------
  36. //    SWCreateSpriteLayer
  37. ///--------------------------------------------------------------------------------------
  38.  
  39. SW_FUNC OSErr SWCreateSpriteLayer(
  40.     SpriteLayerPtr *spriteLayerP)
  41. {
  42.     OSErr err;
  43.     SpriteLayerPtr tempSpriteLayerP;
  44.  
  45.     err = noErr;
  46.     *spriteLayerP = NULL;
  47.  
  48.     tempSpriteLayerP = (SpriteLayerPtr)NewPtrClear((Size)sizeof(SpriteLayerRec));
  49.  
  50.     if (tempSpriteLayerP != NULL)
  51.     {
  52.         tempSpriteLayerP->tileLayer = 10;
  53.         tempSpriteLayerP->isPaused = false;
  54.         tempSpriteLayerP->layerIsNonScrolling = false;
  55.         tempSpriteLayerP->headSpriteP = NULL;
  56.         
  57.         *spriteLayerP = tempSpriteLayerP;
  58.     }
  59.     else
  60.     {
  61.         err = MemError();
  62.     }
  63.  
  64.     SWSetStickyIfError( err );
  65.     return err;
  66. }
  67.  
  68.  
  69. ///--------------------------------------------------------------------------------------
  70. //    SWDisposeSpriteLayer
  71. ///--------------------------------------------------------------------------------------
  72.  
  73. SW_FUNC void SWDisposeSpriteLayer(
  74.     SpriteLayerPtr *spriteLayerPP)
  75. {
  76.     SpriteLayerPtr    spriteLayerP = *spriteLayerPP;
  77.     
  78.     if (spriteLayerP != NULL)
  79.     {
  80.         DisposePtr((Ptr)spriteLayerP);
  81.         *spriteLayerPP = NULL;
  82.     }
  83. }
  84.  
  85.  
  86. ///--------------------------------------------------------------------------------------
  87. //    SWAddSprite
  88. ///--------------------------------------------------------------------------------------
  89.  
  90. SW_FUNC OSErr SWAddSprite(
  91.     SpriteLayerPtr spriteLayerP,
  92.     SpritePtr newSpriteP)
  93. {
  94.     SpritePtr        tailSpriteP = spriteLayerP->tailSpriteP;
  95.     OSErr            err = noErr;
  96.     
  97.     SW_ASSERT(spriteLayerP != NULL);
  98.     SW_ASSERT(newSpriteP != NULL);
  99.     
  100.     if (newSpriteP->parentSpriteLayerP != NULL)
  101.         err = kSpriteAlreadyInLayer;
  102.     
  103.     if (err == noErr)
  104.     {
  105.             // attach the new sprite to the end of the list
  106.             // or make it the head if the list is empty.
  107.         if (tailSpriteP != NULL)
  108.             tailSpriteP->nextSpriteP = newSpriteP;
  109.         else
  110.             spriteLayerP->headSpriteP = newSpriteP;
  111.  
  112.             // link up the new sprite in both directions
  113.         newSpriteP->prevSpriteP = tailSpriteP;
  114.         newSpriteP->nextSpriteP = NULL;
  115.  
  116.             // make the new sprite the tail
  117.         spriteLayerP->tailSpriteP = newSpriteP;
  118.         
  119.             // mark the sprite to be drawn, in case the sprite changed tile layers
  120.         newSpriteP->needsToBeDrawn = true;
  121.  
  122.             // Store the parentSpriteLayer in the Sprite
  123.         newSpriteP->parentSpriteLayerP = spriteLayerP;
  124.     }
  125.     
  126.     SWSetStickyIfError( err );
  127.     return err;
  128. }
  129.  
  130.  
  131. ///--------------------------------------------------------------------------------------
  132. //    SWRemoveSprite
  133. ///--------------------------------------------------------------------------------------
  134.  
  135. SW_FUNC OSErr SWRemoveSprite(
  136.     SpritePtr oldSpriteP)
  137. {
  138.     SpriteLayerPtr    spriteLayerP;
  139.     OSErr            err = noErr;
  140.     
  141.     SW_ASSERT(oldSpriteP != NULL);
  142.     
  143.     spriteLayerP = oldSpriteP->parentSpriteLayerP;
  144.     if (spriteLayerP == NULL)
  145.         err = kBadParameterErr;
  146.     
  147.     if (err == noErr)
  148.     {
  149.             // is this not the tail sprite?
  150.         if (oldSpriteP->nextSpriteP != NULL)
  151.         {
  152.                 // link the next sprite to the prev sprite
  153.             oldSpriteP->nextSpriteP->prevSpriteP = oldSpriteP->prevSpriteP;
  154.         }
  155.         else
  156.         {
  157.                 // make the prev sprite the tail
  158.             spriteLayerP->tailSpriteP = oldSpriteP->prevSpriteP;
  159.         }
  160.  
  161.             // is this not the head sprite?
  162.         if (oldSpriteP->prevSpriteP != NULL)
  163.         {
  164.                 // link the prev sprite to the next sprite
  165.             oldSpriteP->prevSpriteP->nextSpriteP = oldSpriteP->nextSpriteP;
  166.         }
  167.         else
  168.         {
  169.                 // make the next sprite the first sprite
  170.             spriteLayerP->headSpriteP = oldSpriteP->nextSpriteP;
  171.         }
  172.         
  173.         oldSpriteP->parentSpriteLayerP = NULL;
  174.     }
  175.     
  176.     SWSetStickyIfError( err );
  177.     return err;
  178. }
  179.  
  180.  
  181. ///--------------------------------------------------------------------------------------
  182. //    SWRemoveAllSpritesFromLayer
  183. ///--------------------------------------------------------------------------------------
  184.  
  185. SW_FUNC void SWRemoveAllSpritesFromLayer(
  186.     SpriteLayerPtr srcSpriteLayerP)
  187. {
  188.     SpritePtr curSpriteP;
  189.     
  190.     SW_ASSERT(srcSpriteLayerP != NULL);
  191.  
  192.     while ((curSpriteP = SWGetNextSprite(srcSpriteLayerP, NULL)) != NULL)
  193.     {
  194.         SWRemoveSprite(curSpriteP);
  195.     }
  196. }
  197.  
  198.  
  199. ///--------------------------------------------------------------------------------------
  200. //    SWDisposeAllSpritesInLayer
  201. ///--------------------------------------------------------------------------------------
  202.  
  203. SW_FUNC void SWDisposeAllSpritesInLayer(
  204.     SpriteLayerPtr spriteLayerP)
  205. {
  206.     SpritePtr    curSpriteP, nextSpriteP;
  207.     
  208.     SW_ASSERT(spriteLayerP != NULL);
  209.     
  210.     curSpriteP = spriteLayerP->headSpriteP;
  211.     
  212.         // iterate through the sprites in this layer
  213.     while (curSpriteP != NULL)
  214.     {            
  215.         nextSpriteP = curSpriteP->nextSpriteP;
  216.         
  217.         SWRemoveSprite(curSpriteP);
  218.         SWDisposeSprite(&curSpriteP);
  219.         
  220.         curSpriteP = nextSpriteP;
  221.     }
  222. }
  223.  
  224.  
  225. ///--------------------------------------------------------------------------------------
  226. // SWCountNumSpritesInLayer
  227. ///--------------------------------------------------------------------------------------
  228.  
  229. SW_FUNC short SWCountNumSpritesInLayer(
  230.     SpriteLayerPtr spriteLayerP)
  231. {
  232.     SpritePtr        curSpriteP;
  233.     short            numSprites = 0;
  234.     
  235.     SW_ASSERT(spriteLayerP != NULL);
  236.     
  237.     curSpriteP = spriteLayerP->headSpriteP;
  238.     
  239.         // iterate through the sprites in this layer
  240.     while (curSpriteP != NULL)
  241.     {            
  242.         numSprites++;
  243.         curSpriteP = curSpriteP->nextSpriteP;
  244.     }
  245.  
  246.     return numSprites;
  247. }
  248.  
  249. #pragma mark -
  250. ///--------------------------------------------------------------------------------------
  251. //    SWSwapSprite
  252. ///--------------------------------------------------------------------------------------
  253.  
  254. SW_FUNC OSErr SWSwapSprite(
  255.     SpritePtr srcSpriteP,
  256.     SpritePtr dstSpriteP)
  257. {
  258.     SpriteLayerPtr        spriteLayerP;
  259.     register SpritePtr    swapSpriteP;
  260.     OSErr                err = noErr;
  261.     
  262.     SW_ASSERT(srcSpriteP != NULL && dstSpriteP != NULL);
  263.     
  264.         // Do nothing if the sprites are the same
  265.     if (srcSpriteP == dstSpriteP)
  266.         return noErr;
  267.     
  268.     spriteLayerP = srcSpriteP->parentSpriteLayerP;
  269.     if (spriteLayerP != dstSpriteP->parentSpriteLayerP || spriteLayerP == NULL)
  270.     {
  271.         err = kBadParameterErr;
  272.         SWSetStickyIfError( err );
  273.         return err;
  274.     }
  275.     
  276.         // adjacent Sprites are a special case
  277.     if ( srcSpriteP->nextSpriteP == dstSpriteP ||
  278.         dstSpriteP->nextSpriteP == srcSpriteP )
  279.     {
  280.         if ( srcSpriteP->nextSpriteP == dstSpriteP )
  281.         {
  282.             if ( srcSpriteP->prevSpriteP != NULL )
  283.                 (srcSpriteP->prevSpriteP)->nextSpriteP = dstSpriteP;
  284.             if ( dstSpriteP->nextSpriteP != NULL )
  285.                 (dstSpriteP->nextSpriteP)->prevSpriteP = srcSpriteP;
  286.             
  287.             dstSpriteP->prevSpriteP = srcSpriteP->prevSpriteP;
  288.             srcSpriteP->nextSpriteP = dstSpriteP->nextSpriteP;
  289.             
  290.             dstSpriteP->nextSpriteP = srcSpriteP;
  291.             srcSpriteP->prevSpriteP = dstSpriteP;
  292.         }
  293.         else
  294.         {
  295.             if ( dstSpriteP->prevSpriteP != NULL )
  296.                 (dstSpriteP->prevSpriteP)->nextSpriteP = srcSpriteP;
  297.             if ( srcSpriteP->nextSpriteP != NULL )
  298.                 (srcSpriteP->nextSpriteP)->prevSpriteP = dstSpriteP;
  299.             
  300.             srcSpriteP->prevSpriteP = dstSpriteP->prevSpriteP;
  301.             dstSpriteP->nextSpriteP = srcSpriteP->nextSpriteP;
  302.             
  303.             srcSpriteP->nextSpriteP = dstSpriteP;
  304.             dstSpriteP->prevSpriteP = srcSpriteP;
  305.         }
  306.     }
  307.     else
  308.     {
  309.         if (srcSpriteP->prevSpriteP != NULL)
  310.             srcSpriteP->prevSpriteP->nextSpriteP = dstSpriteP;
  311.         if (dstSpriteP->prevSpriteP != NULL)
  312.             dstSpriteP->prevSpriteP->nextSpriteP = srcSpriteP;
  313.         if (srcSpriteP->nextSpriteP != NULL)
  314.             srcSpriteP->nextSpriteP->prevSpriteP = dstSpriteP;
  315.         if (dstSpriteP->nextSpriteP != NULL)
  316.             dstSpriteP->nextSpriteP->prevSpriteP = srcSpriteP;
  317.         
  318.         swapSpriteP = srcSpriteP->nextSpriteP;
  319.         srcSpriteP->nextSpriteP = dstSpriteP->nextSpriteP;
  320.         dstSpriteP->nextSpriteP = swapSpriteP;
  321.  
  322.         swapSpriteP = srcSpriteP->prevSpriteP;
  323.         srcSpriteP->prevSpriteP = dstSpriteP->prevSpriteP;
  324.         dstSpriteP->prevSpriteP = swapSpriteP;
  325.     }
  326.  
  327.  
  328.     if (srcSpriteP->nextSpriteP == NULL)
  329.     {
  330.         spriteLayerP->tailSpriteP = srcSpriteP;
  331.     }
  332.     else if (srcSpriteP->prevSpriteP == NULL)
  333.     {
  334.         spriteLayerP->headSpriteP = srcSpriteP;
  335.     }
  336.  
  337.     if (dstSpriteP->nextSpriteP == NULL)
  338.     {
  339.         spriteLayerP->tailSpriteP = dstSpriteP;
  340.     }
  341.     else if (dstSpriteP->prevSpriteP == NULL)
  342.     {
  343.         spriteLayerP->headSpriteP = dstSpriteP;
  344.     }
  345.     
  346.     return noErr;
  347. }
  348.  
  349.  
  350. ///--------------------------------------------------------------------------------------
  351. //    SWInsertSpriteAfterSprite
  352. ///--------------------------------------------------------------------------------------
  353.  
  354. SW_FUNC OSErr SWInsertSpriteAfterSprite(
  355.     SpritePtr newSpriteP,
  356.     SpritePtr dstSpriteP)
  357. {
  358.     SpriteLayerPtr    spriteLayerP;
  359.     OSErr            err = noErr;
  360.     
  361.     SW_ASSERT(newSpriteP != NULL && dstSpriteP != NULL);
  362.     
  363.     spriteLayerP = dstSpriteP->parentSpriteLayerP;
  364.     if (newSpriteP->parentSpriteLayerP != NULL)
  365.         err = kSpriteAlreadyInLayer;
  366.     
  367.     if (err == noErr)
  368.     {
  369.         if ( dstSpriteP->nextSpriteP != NULL )
  370.             (dstSpriteP->nextSpriteP)->prevSpriteP = newSpriteP;
  371.         
  372.         newSpriteP->nextSpriteP = dstSpriteP->nextSpriteP;
  373.         dstSpriteP->nextSpriteP = newSpriteP;
  374.         newSpriteP->prevSpriteP = dstSpriteP;
  375.         
  376.         if (newSpriteP->nextSpriteP == NULL)
  377.         {
  378.             spriteLayerP->tailSpriteP = newSpriteP;
  379.         }
  380.         
  381.             // mark the sprite to be drawn, in case the sprite changed tile layers
  382.         newSpriteP->needsToBeDrawn = true;
  383.         
  384.         newSpriteP->parentSpriteLayerP = spriteLayerP;
  385.     }
  386.     
  387.     SWSetStickyIfError( err );
  388.     return err;
  389. }
  390.  
  391.  
  392. ///--------------------------------------------------------------------------------------
  393. //    SWInsertSpriteBeforeSprite
  394. ///--------------------------------------------------------------------------------------
  395.  
  396. SW_FUNC OSErr SWInsertSpriteBeforeSprite(
  397.     SpritePtr newSpriteP,
  398.     SpritePtr dstSpriteP)
  399. {
  400.     SpriteLayerPtr    spriteLayerP;
  401.     OSErr            err = noErr;
  402.     
  403.     SW_ASSERT(newSpriteP != NULL && dstSpriteP != NULL);
  404.     
  405.     spriteLayerP = dstSpriteP->parentSpriteLayerP;
  406.     if (newSpriteP->parentSpriteLayerP != NULL)
  407.         err = kSpriteAlreadyInLayer;
  408.     
  409.     if (err == noErr)
  410.     {
  411.         if ( dstSpriteP->prevSpriteP != NULL )
  412.             (dstSpriteP->prevSpriteP)->nextSpriteP = newSpriteP;
  413.         
  414.         newSpriteP->prevSpriteP = dstSpriteP->prevSpriteP;
  415.         dstSpriteP->prevSpriteP = newSpriteP;
  416.         newSpriteP->nextSpriteP = dstSpriteP;
  417.         
  418.         if (newSpriteP->prevSpriteP == NULL)
  419.         {
  420.             spriteLayerP->headSpriteP = newSpriteP;
  421.         }
  422.         
  423.             // mark the sprite to be drawn, in case the sprite changed tile layers
  424.         newSpriteP->needsToBeDrawn = true;
  425.         
  426.         newSpriteP->parentSpriteLayerP = spriteLayerP;
  427.     }
  428.     
  429.     SWSetStickyIfError( err );
  430.     return err;
  431. }
  432.  
  433.  
  434. ///--------------------------------------------------------------------------------------
  435. //    SWGetNextSprite
  436. ///--------------------------------------------------------------------------------------
  437.  
  438. SW_FUNC SpritePtr SWGetNextSprite(
  439.     SpriteLayerPtr spriteLayerP,
  440.     SpritePtr curSpriteP)
  441. {
  442.     SW_ASSERT(spriteLayerP != NULL);
  443.     
  444.     return (curSpriteP == NULL) ? spriteLayerP->headSpriteP : curSpriteP->nextSpriteP;
  445. }
  446.  
  447.  
  448. ///--------------------------------------------------------------------------------------
  449. //    SWGetPreviousSprite
  450. ///--------------------------------------------------------------------------------------
  451.  
  452. SW_FUNC SpritePtr SWGetPreviousSprite(
  453.     SpriteLayerPtr spriteLayerP,
  454.     SpritePtr curSpriteP)
  455. {
  456.     SW_ASSERT(spriteLayerP != NULL);
  457.     
  458.     return (curSpriteP == NULL) ? spriteLayerP->tailSpriteP : curSpriteP->prevSpriteP;
  459. }
  460.  
  461.  
  462. #pragma mark -
  463. ///--------------------------------------------------------------------------------------
  464. //    SWLockSpriteLayer
  465. ///--------------------------------------------------------------------------------------
  466.  
  467. SW_FUNC void SWLockSpriteLayer(
  468.     SpriteLayerPtr spriteLayerP)
  469. {
  470.     SpritePtr curSpriteP;
  471.     
  472.     SW_ASSERT(spriteLayerP != NULL);
  473.  
  474.     curSpriteP = spriteLayerP->headSpriteP;
  475.  
  476.     while (curSpriteP != NULL)
  477.     {
  478.         SWLockSprite(curSpriteP);
  479.  
  480.         curSpriteP = curSpriteP->nextSpriteP;
  481.     }
  482. }
  483.  
  484.  
  485. ///--------------------------------------------------------------------------------------
  486. //    SWUnlockSpriteLayer
  487. ///--------------------------------------------------------------------------------------
  488.  
  489. SW_FUNC void SWUnlockSpriteLayer(
  490.     SpriteLayerPtr spriteLayerP)
  491. {
  492.     SpritePtr curSpriteP;
  493.     
  494.     SW_ASSERT(spriteLayerP != NULL);
  495.  
  496.     curSpriteP = spriteLayerP->headSpriteP;
  497.  
  498.     while (curSpriteP != NULL)
  499.     {
  500.         SWUnlockSprite(curSpriteP);
  501.  
  502.         curSpriteP = curSpriteP->nextSpriteP;
  503.     }
  504. }
  505.  
  506.  
  507. ///--------------------------------------------------------------------------------------
  508. //    SWCollideSpriteLayer
  509. ///--------------------------------------------------------------------------------------
  510.  
  511. SW_FUNC void SWCollideSpriteLayer(
  512.     SpriteWorldPtr    spriteWorldP,
  513.     SpriteLayerPtr srcSpriteLayerP,
  514.     SpriteLayerPtr dstSpriteLayerP)
  515. {
  516.     SpritePtr    srcSpriteP, nextSrcSpriteP;
  517.     SpritePtr    dstSpriteP, nextDstSpriteP;
  518.     Rect        sectRect;
  519.     Boolean        collisionOccurred;
  520.     
  521.     SW_ASSERT(spriteWorldP != NULL);
  522.     SW_ASSERT(srcSpriteLayerP != NULL && dstSpriteLayerP != NULL);
  523.     
  524.         // Don't check for collisions unless the frame has been processed!
  525.     if (!spriteWorldP->frameHasOccurred)
  526.         return;
  527.  
  528.     srcSpriteP = srcSpriteLayerP->headSpriteP;
  529.  
  530.     while (srcSpriteP != NULL)
  531.     {
  532.         dstSpriteP = dstSpriteLayerP->headSpriteP;
  533.         nextSrcSpriteP = srcSpriteP->nextSpriteP;
  534.  
  535.         while (dstSpriteP != NULL)
  536.         {
  537.             nextDstSpriteP = dstSpriteP->nextSpriteP;
  538.             
  539.             if (srcSpriteP != dstSpriteP)
  540.             {
  541.                     // are the sprite’s rectangles overlapping?
  542.                 if ((srcSpriteP->destFrameRect.top < dstSpriteP->destFrameRect.bottom) &&
  543.                     (srcSpriteP->destFrameRect.bottom > dstSpriteP->destFrameRect.top) &&
  544.                     (srcSpriteP->destFrameRect.left < dstSpriteP->destFrameRect.right) &&
  545.                     (srcSpriteP->destFrameRect.right > dstSpriteP->destFrameRect.left))
  546.                 {
  547.                         // Once we've determined that a collision has occurred, do some
  548.                         // more precise checking if a collisionInset is used.
  549.                     if (srcSpriteP->curFrameP->usesCollisionInset ||
  550.                         dstSpriteP->curFrameP->usesCollisionInset)
  551.                     {
  552.                         collisionOccurred = 
  553.                             ((SW_COLLISION_RECT_TOP(srcSpriteP) < SW_COLLISION_RECT_BOTTOM(dstSpriteP)) &&
  554.                             (SW_COLLISION_RECT_BOTTOM(srcSpriteP) > SW_COLLISION_RECT_TOP(dstSpriteP)) &&
  555.                             (SW_COLLISION_RECT_LEFT(srcSpriteP) < SW_COLLISION_RECT_RIGHT(dstSpriteP)) &&
  556.                             (SW_COLLISION_RECT_RIGHT(srcSpriteP) > SW_COLLISION_RECT_LEFT(dstSpriteP)) );
  557.                     }
  558.                     else
  559.                     {
  560.                         collisionOccurred = true;
  561.                     }
  562.                     
  563.                     
  564.                     
  565.                         // call the source sprite’s collision routine
  566.                     if (collisionOccurred && srcSpriteP->spriteCollideProc != NULL)
  567.                     {
  568.                             // Note: the following expands to something much larger  
  569.                             // than you might think; try preprocessing and you'll see.
  570.                         sectRect.left =
  571.                             SW_MAX(SW_COLLISION_RECT_LEFT(srcSpriteP), SW_COLLISION_RECT_LEFT(dstSpriteP));
  572.                         sectRect.top =
  573.                             SW_MAX(SW_COLLISION_RECT_TOP(srcSpriteP), SW_COLLISION_RECT_TOP(dstSpriteP));
  574.                         sectRect.right =
  575.                             SW_MIN(SW_COLLISION_RECT_RIGHT(srcSpriteP), SW_COLLISION_RECT_RIGHT(dstSpriteP));
  576.                         sectRect.bottom =
  577.                             SW_MIN(SW_COLLISION_RECT_BOTTOM(srcSpriteP), SW_COLLISION_RECT_BOTTOM(dstSpriteP));
  578.                         
  579.     /*                    
  580.                         sectRect.left =
  581.                             SW_MAX(srcSpriteP->destFrameRect.left, dstSpriteP->destFrameRect.left);
  582.                         sectRect.top =
  583.                             SW_MAX(srcSpriteP->destFrameRect.top, dstSpriteP->destFrameRect.top);
  584.                         sectRect.right =
  585.                             SW_MIN(srcSpriteP->destFrameRect.right, dstSpriteP->destFrameRect.right);
  586.                         sectRect.bottom =
  587.                             SW_MIN(srcSpriteP->destFrameRect.bottom, dstSpriteP->destFrameRect.bottom);
  588.     */
  589.                         (*srcSpriteP->spriteCollideProc)(srcSpriteP, dstSpriteP, §Rect);
  590.                         
  591.                             // If the srcSpriteP was removed from the layer, collisions
  592.                             // between it and other Sprites shouldn't be detected anymore.
  593.                             // To avoid this, we begin processing the next srcSpriteP.
  594.                         if (srcSpriteP->spriteRemoval != kSWDontRemoveSprite ||
  595.                             srcSpriteP->parentSpriteLayerP == NULL)
  596.                         {
  597.                             break;
  598.                         }
  599.                     }
  600.                 }
  601.             }
  602.             
  603.                 // If the nextDstSpriteP has been removed, we must start over again
  604.             if (nextDstSpriteP != NULL && nextDstSpriteP->spriteRemoval != kSWDontRemoveSprite)
  605.                 dstSpriteP = dstSpriteLayerP->headSpriteP;
  606.             else
  607.                 dstSpriteP = nextDstSpriteP;
  608.         }
  609.         
  610.             // If the nextSrcSpriteP has been removed, we must start over again
  611.         if (nextSrcSpriteP != NULL && nextSrcSpriteP->spriteRemoval != kSWDontRemoveSprite)
  612.             srcSpriteP = srcSpriteLayerP->headSpriteP;
  613.         else
  614.             srcSpriteP = nextSrcSpriteP;
  615.     }
  616. }
  617.  
  618.  
  619.     // The following line defines the sort criteria for SWSortSpriteLayer
  620.     // topSpriteP is a Sprite that, unless sorted, will be drawn on top of bottomSpriteP.
  621.     // If the statement below is true, topSpriteP will be placed under bottomSpriteP.
  622. #define SortCriteria(bottomSpriteP, topSpriteP)    \
  623.     if (bottomSpriteP->destFrameRect.bottom > topSpriteP->destFrameRect.bottom)
  624.  
  625. ///--------------------------------------------------------------------------------------
  626. //    SWSortSpriteLayer - Performs insertion sort on the sprite layer. 
  627. //  Code contributed by Arjun Raj <arjun@uclink4.berkeley.edu>
  628. ///--------------------------------------------------------------------------------------
  629.  
  630. SW_FUNC void SWSortSpriteLayer(SpriteLayerPtr theLayer)
  631. {
  632.     SpritePtr    curSpriteP, prevSprite, insertSprite;
  633.     Boolean        done;
  634.     
  635.     prevSprite = theLayer->headSpriteP;
  636.     curSpriteP = SWGetNextSprite(theLayer, prevSprite);
  637.     
  638.     while (curSpriteP != NULL)
  639.     {
  640. //        if (prevSprite->destFrameRect.bottom > curSpriteP->destFrameRect.bottom)
  641.         SortCriteria(prevSprite, curSpriteP)
  642.         {
  643.             insertSprite = curSpriteP->prevSpriteP;
  644.             done = false;
  645.             
  646.             while (insertSprite != NULL && !done)
  647.             {
  648. //                if (insertSprite->destFrameRect.bottom > curSpriteP->destFrameRect.bottom)
  649.                 SortCriteria(insertSprite, curSpriteP)
  650.                     insertSprite = insertSprite->prevSpriteP;
  651.                 else
  652.                     done = true;
  653.             }
  654.             
  655.             if (insertSprite != NULL)
  656.             {
  657.                 SWRemoveSprite(curSpriteP);
  658.  
  659.                 SWInsertSpriteAfterSprite(curSpriteP, insertSprite);
  660.                 curSpriteP = SWGetNextSprite(theLayer, prevSprite);
  661.             }
  662.             else
  663.             {
  664.                 SWRemoveSprite(curSpriteP);
  665.                 
  666.                 SWInsertSpriteBeforeSprite(curSpriteP, theLayer->headSpriteP);
  667.                 curSpriteP = SWGetNextSprite(theLayer, prevSprite);
  668.             }
  669.         }
  670.         else
  671.         {
  672.             prevSprite = curSpriteP;
  673.             curSpriteP = curSpriteP->nextSpriteP;
  674.         }
  675.     }
  676. }
  677.  
  678.  
  679. ///--------------------------------------------------------------------------------------
  680. //    SWPauseSpriteLayer
  681. ///--------------------------------------------------------------------------------------
  682.  
  683. SW_FUNC void SWPauseSpriteLayer(
  684.     SpriteLayerPtr    spriteLayerP)
  685. {
  686.     SW_ASSERT(spriteLayerP != NULL);
  687.     
  688.     spriteLayerP->isPaused = true;
  689. }
  690.  
  691.  
  692. ///--------------------------------------------------------------------------------------
  693. //    SWUnpauseSpriteLayer
  694. ///--------------------------------------------------------------------------------------
  695.  
  696. SW_FUNC void SWUnpauseSpriteLayer(
  697.     SpriteLayerPtr    spriteLayerP)
  698. {
  699.     SW_ASSERT(spriteLayerP != NULL);
  700.     
  701.     spriteLayerP->isPaused = false;
  702. }
  703.  
  704.  
  705. ///--------------------------------------------------------------------------------------
  706. //    SWSetLayerAsNonScrolling
  707. ///--------------------------------------------------------------------------------------
  708.  
  709. SW_FUNC void SWSetLayerAsNonScrolling(
  710.     SpriteLayerPtr    spriteLayerP,
  711.     Boolean layerIsNonScrolling)
  712. {
  713.     SW_ASSERT(spriteLayerP != NULL);
  714.     
  715.     spriteLayerP->layerIsNonScrolling = layerIsNonScrolling;
  716. }
  717.  
  718.  
  719. ///--------------------------------------------------------------------------------------
  720. //    SWFindSpriteByPoint
  721. ///--------------------------------------------------------------------------------------
  722.  
  723. SW_FUNC SpritePtr SWFindSpriteByPoint(
  724.     SpriteLayerPtr spriteLayerP,
  725.     SpritePtr startSpriteP,
  726.     Point testPoint)
  727. {
  728.     SpritePtr curSpriteP;
  729.     
  730.     SW_ASSERT(spriteLayerP != NULL);
  731.  
  732.     curSpriteP = (startSpriteP == NULL) ? spriteLayerP->tailSpriteP : startSpriteP;
  733.  
  734.         // note that we traverse the sprites in reverse order
  735.         // since this will make the most sense if we are
  736.         // looking for a sprite that was clicked
  737.     while ((curSpriteP != NULL) && !SWIsPointInSprite(curSpriteP, testPoint))
  738.     {
  739.         curSpriteP = curSpriteP->prevSpriteP;
  740.     }
  741.  
  742.     return curSpriteP;
  743. }
  744.